package cn.gaaidou.rpc.framework;

import cn.gaaidou.common.utils.IOUtil;
import cn.gaaidou.common.utils.JdkSerializationUtil;
import cn.gaaidou.rpc.framework.vo.RpcClassMapperVo;
import cn.gaaidou.rpc.framework.vo.RpcReqVo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Martin
 * @date 2021/7/5 17:53
 */
public class RpcClientProxy implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        /*
         * 1、Socket客户端连接服务端
         * 如果是市面RPC框架, 可以通过注册中心和客户端负载均衡来获取服务提供者的IP + Port
         */
        Socket socket = new Socket("127.0.0.1", 8080);

        // 2、创建请求参数, 请求服务端
        // 方法参数类型和值的映射关系, 主要用于服务端寻找具体的实现方法
        List<RpcClassMapperVo> argsClazzMapper = Arrays
                .stream(args)
                .map(v -> new RpcClassMapperVo(v.getClass(), JdkSerializationUtil.serialize(v)))
                .collect(Collectors.toList());
        // 请求参数封装类
        RpcReqVo rpcReqVo = new RpcReqVo(method.getDeclaringClass().getName(), method.getName(), argsClazzMapper);
        socket.getOutputStream().write(JdkSerializationUtil.serialize(rpcReqVo));

        // 3、反序列化服务端返回的结果
        return JdkSerializationUtil.deserialize(IOUtil.readSocket(socket.getInputStream()));
    }
}
